package com.czk.bootlettuce.controller;

import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.List;

/**
 * redis bitmaps实现签到功能->按月份进行实现
 *
 * @Author:ChenZhangKun
 * @Date: 2021/12/5 16:37
 */
@RequestMapping("/sign")
@RestController
public class SignController {
    /**
     * 月份签到key
     */
    private static final String month = "sign:"+LocalDate.now().getMonthValue();
    @Resource
    private RedisTemplate redisTemplate;

    @GetMapping("/{username}")
    public String sign(@PathVariable String username) {
        int dayOfMonth = LocalDate.now().getDayOfMonth();
        // 前一天是否签到
        boolean signed = this.isSigned(username);
        if (signed) {
            String key = month + ":" + username;
            Boolean aBoolean = redisTemplate.opsForValue().setBit(key, dayOfMonth, true);
            if (aBoolean) {
                return "签到失败";
            } else {
                return "签到成功";
            }
        }
        return "对不起，你已经漏签，不能签到";
    }

    /**
     * 前一天是否签到
     *
     * @param username
     * @return
     */
    private boolean isSigned(String username) {
        String key = month + ":" + username;
        int preDay = LocalDate.now().getDayOfMonth() - 1;
        Boolean bit = redisTemplate.opsForValue().getBit(key, preDay);
        return bit;
    }

    /**
     * 连续签到多少天
     *
     * @param username
     * @param limit
     * @param offset
     * @return
     */
    @GetMapping("/consitant/{username}/{limit}/{offset}")
    public List<Long> signCountDays(@PathVariable String username, @PathVariable int limit, @PathVariable int offset) {
        String key = month + ":" + username;
        Object execute = redisTemplate.execute((RedisCallback<List<Long>>) con ->
                con.bitField(key.getBytes(),
                        BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(limit)).valueAt(offset)));
        return (List<Long>) execute;
    }

    /**
     * 当月签到总数
     *
     * @param username
     * @return
     */
    @GetMapping("/count/{username}")
    public Long getCount(@PathVariable String username) {
        String key = month + ":" + username;
        Object execute = redisTemplate.execute((RedisCallback<Long>) con -> con.bitCount(key.getBytes()));
        return (Long) execute;
    }
}
